home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Power Programmierung
/
Power-Programmierung (Tewi)(1994).iso
/
magazine
/
drdobbs
/
1991
/
05
/
c_prog.asc
< prev
next >
Wrap
Text File
|
1991-03-15
|
29KB
|
971 lines
_C PROGRAMMING COLUMN_
by Al Stevens
[LISTING ONE]
/* ------------- dflat.h ----------- */
#ifndef WINDOW_H
#define WINDOW_H
#define TRUE 1
#define FALSE 0
#include "system.h"
#include "config.h"
#include "rect.h"
#include "menu.h"
#include "keys.h"
#include "commands.h"
#include "config.h"
#include "dialbox.h"
/* ------ integer type for message parameters ----- */
typedef long PARAM;
typedef enum window_class {
NORMAL,
APPLICATION,
TEXTBOX,
LISTBOX,
EDITBOX,
MENUBAR,
POPDOWNMENU,
BUTTON,
DIALOG,
ERRORBOX,
MESSAGEBOX,
HELPBOX,
TEXT,
RADIOBUTTON,
DUMMY
} CLASS;
typedef struct window {
CLASS class; /* window class */
char *title; /* window title */
struct window *parent; /* parent window */
int (*wndproc)
(struct window *, enum messages, PARAM, PARAM);
/* ---------------- window dimensions ----------------- */
RECT rc; /* window coordinates
(0/0 to 79/24) */
int ht, wd; /* window height and width */
RECT RestoredRC; /* restored condition rect */
/* -------------- linked list pointers ---------------- */
struct window *next; /* next window on screen */
struct window *prev; /* previous window on screen*/
struct window *nextbuilt; /* next window built */
struct window *prevbuilt; /* previous window built */
int attrib; /* Window attributes */
char *videosave; /* video save buffer */
int condition; /* Restored, Maximized,
Minimized */
void *extension; /* -> menus, dialog box, etc*/
struct window *PrevMouse;
struct window *PrevKeyboard;
/* ----------------- text box fields ------------------ */
int wlines; /* number of lines of text */
int wtop; /* text line that is on the top display */
char *text; /* window text */
int textlen; /* text length */
int wleft; /* left position in window viewport */
int textwidth; /* width of longest line in textbox */
int BlkBegLine; /* beginning line of marked block */
int BlkBegCol; /* beginning column of marked block */
int BlkEndLine; /* ending line of marked block */
int BlkEndCol; /* ending column of marked block */
int HScrollBox; /* position of horizontal scroll box */
int VScrollBox; /* position of vertical scroll box */
/* ------------------ list box field ------------------ */
int selection; /* current selection */
/* ----------------- edit box fields ------------------ */
int CurrCol; /* Current column */
char *CurrLine; /* Current line */
int WndRow; /* Current window row */
int TextChanged; /* TRUE if text has changed */
char *DeletedText; /* for undo */
int DeletedLength; /* " " */
/* ---------------- dialog box fields ----------------- */
struct window *dFocus; /* control that has the focus */
int ReturnCode; /* return code from a dialog box */
} * WINDOW;
#include "message.h"
#include "classdef.h"
#include "video.h"
enum Condition {
ISRESTORED, ISMINIMIZED, ISMAXIMIZED
};
/* ------- window methods ----------- */
#define WindowHeight(w) ((w)->ht)
#define WindowWidth(w) ((w)->wd)
#define BorderAdj(w,n) (TestAttribute(w,HASBORDER)?n:0)
#define ClientWidth(w) (WindowWidth(w)-BorderAdj(w,2))
#define ClientHeight(w) (WindowHeight(w)-BorderAdj(w,2))
#define WindowRect(w) ((w)->rc)
#define GetTop(w) (RectTop(WindowRect(w)))
#define GetBottom(w) (RectBottom(WindowRect(w)))
#define GetLeft(w) (RectLeft(WindowRect(w)))
#define GetRight(w) (RectRight(WindowRect(w)))
#define GetClientTop(w) (GetTop(w)+BorderAdj(w,1))
#define GetClientBottom(w) (GetBottom(w)-BorderAdj(w,1))
#define GetClientLeft(w) (GetLeft(w)+BorderAdj(w,1))
#define GetClientRight(w) (GetRight(w)-BorderAdj(w,1))
#define GetParent(w) ((w)->parent)
#define GetTitle(w) ((w)->title)
#define NextWindow(w) ((w)->next)
#define PrevWindow(w) ((w)->prev)
#define NextWindowBuilt(w) ((w)->nextbuilt)
#define PrevWindowBuilt(w) ((w)->prevbuilt)
#define GetClass(w) ((w)->class)
#define GetAttribute(w) ((w)->attrib)
#define AddAttribute(w,a) (GetAttribute(w) |= a)
#define ClearAttribute(w,a) (GetAttribute(w) &= ~(a))
#define TestAttribute(w,a) (GetAttribute(w) & (a))
#define isVisible(w) (GetAttribute(w) & VISIBLE)
#define SetVisible(w) (GetAttribute(w) |= VISIBLE)
#define ClearVisible(w) (GetAttribute(w) &= ~VISIBLE)
#define gotoxy(w,x,y) cursor(w->rc.lf+(x)+1,w->rc.tp+(y)+1)
WINDOW CreateWindow(CLASS,char *,int,int,int,int,void*,WINDOW,
int (*)(struct window *,enum messages,PARAM,PARAM),int);
void AddTitle(WINDOW, char *);
void RepaintBorder(WINDOW, RECT *);
void ClearWindow(WINDOW, RECT *, int);
void clipline(WINDOW, int, char *);
void writeline(WINDOW, char *, int, int, int);
void writefull(WINDOW, char *, int);
void SetNextFocus(WINDOW,int);
void PutWindowChar(WINDOW, int, int, int);
void GetVideoBuffer(WINDOW);
void RestoreVideoBuffer(WINDOW);
int LineLength(char *);
#define DisplayBorder(wnd) RepaintBorder(wnd, NULL)
#define DefaultWndProc(wnd,msg,p1,p2) \
classdefs[FindClass(wnd->class)].wndproc(wnd,msg,p1,p2)
#define BaseWndProc(class,wnd,msg,p1,p2) \
classdefs[DerivedClass(class)].wndproc(wnd,msg,p1,p2)
#define NULLWND ((WINDOW) 0)
struct LinkedList {
WINDOW FirstWindow;
WINDOW LastWindow;
};
extern struct LinkedList Focus;
extern struct LinkedList Built;
extern WINDOW inFocus;
extern WINDOW CaptureMouse;
extern WINDOW CaptureKeyboard;
extern int foreground, background;
extern int WindowMoving;
extern int WindowSizing;
extern int TextMarking;
extern char *Clipboard;
extern WINDOW SystemMenuWnd;
/* --------------- border characters ------------- */
#define FOCUS_NW '\xc9'
#define FOCUS_NE '\xbb'
#define FOCUS_SE '\xbc'
#define FOCUS_SW '\xc8'
#define FOCUS_SIDE '\xba'
#define FOCUS_LINE '\xcd'
#define NW '\xda'
#define NE '\xbf'
#define SE '\xd9'
#define SW '\xc0'
#define SIDE '\xb3'
#define LINE '\xc4'
#define LEDGE '\xc3'
#define REDGE '\xb4'
#define SHADOWFG DARKGRAY
/* ------------- scroll bar characters ------------ */
#define UPSCROLLBOX '\x1e'
#define DOWNSCROLLBOX '\x1f'
#define LEFTSCROLLBOX '\x11'
#define RIGHTSCROLLBOX '\x10'
#define SCROLLBARCHAR 176
#define SCROLLBOXCHAR 178
#define CHECKMARK 251 /* menu item toggle */
/* ----------------- title bar characters ----------------- */
#define CONTROLBOXCHAR '\xf0'
#define MAXPOINTER 24 /* maximize token */
#define MINPOINTER 25 /* minimize token */
#define RESTOREPOINTER 18 /* restore token */
/* --------------- text control characters ---------------- */
#define APPLCHAR 176 /* fills application window */
#define SHORTCUTCHAR '~' /* prefix: shortcut key display */
#define CHANGECOLOR 174 /* prefix to change colors */
#define RESETCOLOR 175 /* reset colors to default */
/* ---- standard window message processing prototypes ----- */
int ApplicationProc(WINDOW, MESSAGE, PARAM, PARAM);
int NormalProc(WINDOW, MESSAGE, PARAM, PARAM);
int TextBoxProc(WINDOW, MESSAGE, PARAM, PARAM);
int ListBoxProc(WINDOW, MESSAGE, PARAM, PARAM);
int EditBoxProc(WINDOW, MESSAGE, PARAM, PARAM);
int MenuBarProc(WINDOW, MESSAGE, PARAM, PARAM);
int PopDownProc(WINDOW, MESSAGE, PARAM, PARAM);
int ButtonProc(WINDOW, MESSAGE, PARAM, PARAM);
int DialogProc(WINDOW, MESSAGE, PARAM, PARAM);
int SystemMenuProc(WINDOW, MESSAGE, PARAM, PARAM);
int HelpBoxProc(WINDOW, MESSAGE, PARAM, PARAM);
int MessageBoxProc(WINDOW, MESSAGE, PARAM, PARAM);
/* ------------- normal box prototypes ------------- */
int isWindow(WINDOW);
WINDOW inWindow(int, int);
int WndForeground(WINDOW);
int WndBackground(WINDOW);
int FrameForeground(WINDOW);
int FrameBackground(WINDOW);
int SelectForeground(WINDOW);
int SelectBackground(WINDOW);
void SetStandardColor(WINDOW);
void SetReverseColor(WINDOW);
void SetClassColors(CLASS);
WINDOW GetFirstChild(WINDOW);
WINDOW GetNextChild(WINDOW);
WINDOW GetLastChild(WINDOW);
WINDOW GetPrevChild(WINDOW);
#define HitControlBox(wnd, p1, p2) \
(TestAttribute(wnd, TITLEBAR) && \
TestAttribute(wnd, CONTROLBOX) && \
p1 == 2 && p2 == 0)
/* -------- text box prototypes ---------- */
char *TextLine(WINDOW, int);
void WriteTextLine(WINDOW, RECT *, int, int);
void SetTextBlock(WINDOW, int, int, int, int);
#define BlockMarked(wnd) ( wnd->BlkBegLine || \
wnd->BlkEndLine || \
wnd->BlkBegCol || \
wnd->BlkEndCol)
#define ClearBlock(wnd) wnd->BlkBegLine = wnd->BlkEndLine = \
wnd->BlkBegCol = wnd->BlkEndCol = 0;
#define GetText(w) ((w)->text)
/* --------- menu prototypes ---------- */
int CopyCommand(char *, char *, int, int);
void PrepOptionsMenu(void *, struct Menu *);
void PrepEditMenu(void *, struct Menu *);
void PrepWindowMenu(void *, struct Menu *);
void BuildSystemMenu(WINDOW);
/* ------------- edit box prototypes ----------- */
#define isMultiLine(wnd) TestAttribute(wnd, MULTILINE)
/* --------- message box prototypes -------- */
void MessageBox(char *, char *);
void ErrorMessage(char *);
int TestErrorMessage(char *);
int YesNoBox(char *);
int MsgHeight(char *);
int MsgWidth(char *);
/* ------------- dialog box prototypes -------------- */
int DialogBox(DBOX *, int (*)(struct window *,
enum messages, PARAM, PARAM));
int DlgOpenFile(char *, char *);
int DlgSaveAs(char *);
void GetDlgListText(WINDOW, char *, enum commands);
int DlgDirList(WINDOW, char *, enum commands,
enum commands, unsigned);
int RadioButtonSetting(DBOX *, enum commands);
void PushRadioButton(DBOX *, enum commands);
void PutItemText(WINDOW, enum commands, char *);
void GetItemText(WINDOW, enum commands, char *, int);
/* ------------- help box prototypes ------------- */
void HelpFunction(void);
void LoadHelpFile(void);
#define swap(a,b){int x=a;a=b;b=x;}
#endif
[LISTING TWO]
/* ----------- keys.h ------------ */
#ifndef KEYS_H
#define KEYS_H
#define RUBOUT 8
#define BELL 7
#define ESC 27
#define ALT_BS 197
#define SHIFT_DEL 198
#define CTRL_INS 186
#define SHIFT_INS 185
#define F1 187
#define F2 188
#define F3 189
#define F4 190
#define F5 191
#define F6 192
#define F7 193
#define F8 194
#define F9 195
#define F10 196
#define CTRL_F1 222
#define CTRL_F2 223
#define CTRL_F3 224
#define CTRL_F4 225
#define CTRL_F5 226
#define CTRL_F6 227
#define CTRL_F7 228
#define CTRL_F8 229
#define CTRL_F9 230
#define CTRL_F10 231
#define ALT_F1 232
#define ALT_F2 233
#define ALT_F3 234
#define ALT_F4 235
#define ALT_F5 236
#define ALT_F6 237
#define ALT_F7 238
#define ALT_F8 239
#define ALT_F9 240
#define ALT_F10 241
#define HOME 199
#define UP 200
#define PGUP 201
#define BS 203
#define FWD 205
#define END 207
#define DN 208
#define PGDN 209
#define INS 210
#define DEL 211
#define CTRL_HOME 247
#define CTRL_PGUP 132
#define CTRL_BS 243
#define CTRL_FIVE 143
#define CTRL_FWD 244
#define CTRL_END 245
#define CTRL_PGDN 246
#define SHIFT_HT 143
#define ALT_A 158
#define ALT_B 176
#define ALT_C 174
#define ALT_D 160
#define ALT_E 146
#define ALT_F 161
#define ALT_G 162
#define ALT_H 163
#define ALT_I 151
#define ALT_J 164
#define ALT_K 165
#define ALT_L 166
#define ALT_M 178
#define ALT_N 177
#define ALT_O 152
#define ALT_P 153
#define ALT_Q 144
#define ALT_R 147
#define ALT_S 159
#define ALT_T 148
#define ALT_U 150
#define ALT_V 175
#define ALT_W 145
#define ALT_X 173
#define ALT_Y 149
#define ALT_Z 172
#define ALT_1 0xf8
#define ALT_2 0xf9
#define ALT_3 0xfa
#define ALT_4 0xfb
#define ALT_5 0xfc
#define ALT_6 0xfd
#define ALT_7 0xfe
#define ALT_8 0xff
#define ALT_9 0x80
#define ALT_0 0x81
#define ALT_HYPHEN 130
#define RIGHTSHIFT 0x01
#define LEFTSHIFT 0x02
#define CTRLKEY 0x04
#define ALTKEY 0x08
#define SCROLLLOCK 0x10
#define NUMLOCK 0x20
#define CAPSLOCK 0x40
#define INSERTKEY 0x80
struct keys {
int keycode;
char *keylabel;
};
int getkey(void);
int getshift(void);
int keyhit(void);
void beep(void);
extern struct keys keys[];
extern char altconvert[];
#endif
[LISTING THREE]
/* --------------- system.h -------------- */
#ifndef SYSTEM_H
#define SYSTEM_H
/* ----- interrupt vectors ----- */
#define TIMER 8
#define VIDEO 0x10
#define KEYBRD 0x16
#define DOS 0x21
#define CRIT 0x24
#define MOUSE 0x33
/* ------- platform-dependent values ------ */
#define FREQUENCY 100
#define COUNT (1193280L / FREQUENCY)
#define ZEROFLAG 0x40
#define MAXSAVES 50
#define SCREENWIDTH 80
#define SCREENHEIGHT 25
/* ----- keyboard BIOS (0x16) functions -------- */
#define READKB 0
#define KBSTAT 1
/* ------- video BIOS (0x10) functions --------- */
#define SETCURSORTYPE 1
#define SETCURSOR 2
#define READCURSOR 3
#define READATTRCHAR 8
#define WRITEATTRCHAR 9
#define HIDECURSOR 0x20
/* ------- the interrupt function registers -------- */
typedef struct {
int bp,di,si,ds,es,dx,cx,bx,ax,ip,cs,fl;
} IREGS;
/* ---------- cursor prototypes -------- */
void curr_cursor(int *x, int *y);
void cursor(int x, int y);
void hidecursor(void);
void unhidecursor(void);
void savecursor(void);
void restorecursor(void);
void normalcursor(void);
void set_cursor_type(unsigned t);
void videomode(void);
/* ---------- mouse prototypes ---------- */
int mouse_installed(void);
int mousebuttons(void);
void get_mouseposition(int *x, int *y);
void set_mouseposition(int x, int y);
void show_mousecursor(void);
void hide_mousecursor(void);
int button_releases(void);
void resetmouse(void);
#define leftbutton() (mousebuttons()&1)
#define rightbutton() (mousebuttons()&2)
#define waitformouse() while(mousebuttons());
/* ------------ timer macros -------------- */
#define timed_out(timer) (timer==0)
#define set_timer(timer, secs) timer=(secs)*182/10+1
#define disable_timer(timer) timer = -1
#define timer_running(timer) (timer > 0)
#define countdown(timer) --timer
#define timer_disabled(timer) (timer == -1)
#ifdef MSC
/* ============= MSC Compatibility Macros ============ */
#define BLACK 0
#define BLUE 1
#define GREEN 2
#define CYAN 3
#define RED 4
#define MAGENTA 5
#define BROWN 6
#define LIGHTGRAY 7
#define DARKGRAY 8
#define LIGHTBLUE 9
#define LIGHTGREEN 10
#define LIGHTCYAN 11
#define LIGHTRED 12
#define LIGHTMAGENTA 13
#define YELLOW 14
#define WHITE 15
#define getvect(v) _dos_getvect(v)
#define setvect(v,f) _dos_setvect(v,f)
#define MK_FP(s,o) ((void far *) \
(((unsigned long)(s) << 16) | (unsigned)(o)))
#undef FP_OFF
#undef FP_SEG
#define FP_OFF(p) ((unsigned)(p))
#define FP_SEG(p) ((unsigned)((unsigned long)(p) >> 16))
#define poke(a,b,c) (*((int far*)MK_FP((a),(b))) = (int)(c))
#define pokeb(a,b,c) (*((char far*)MK_FP((a),(b))) = (char)(c))
#define peek(a,b) (*((int far*)MK_FP((a),(b))))
#define peekb(a,b) (*((char far*)MK_FP((a),(b))))
#define findfirst(p,f,a) _dos_findfirst(p,a,f)
#define findnext(f) _dos_findnext(f)
#define ffblk find_t
#define ff_name name
#define ff_fsize size
#define ff_attrib attrib
#define fnsplit _splitpath
#define fnmerge _makepath
#define EXTENSION 2
#define FILENAME 4
#define DIRECTORY 8
#define DRIVE 16
#define MAXPATH 80
#define MAXDRIVE 3
#define MAXDIR 66
#define MAXFILE 9
#define MAXEXT 5
#define setdisk(d) _dos_setdrive((d)+1, NULL)
#define bioskey _bios_keybrd
#define keyhit kbhit
#endif
#endif
[LISTING FOUR]
/* ----------- rect.h ------------ */
#ifndef RECT_H
#define RECT_H
typedef struct {
int lf,tp,rt,bt;
} RECT;
#define within(p,v1,v2) ((p)>=(v1)&&(p)<=(v2))
#define RectTop(r) (r.tp)
#define RectBottom(r) (r.bt)
#define RectLeft(r) (r.lf)
#define RectRight(r) (r.rt)
#define InsideRect(x,y,r) (within(x,RectLeft(r),RectRight(r)) \
&& \
within(y,RectTop(r),RectBottom(r)))
#define ValidRect(r) (RectRight(r) || RectLeft(r))
#define RectWidth(r) (RectRight(r)-RectLeft(r)+1)
#define RectHeight(r) (RectBottom(r)-RectTop(r)+1)
RECT subRectangle(RECT, RECT);
RECT RelativeRectangle(RECT, RECT);
RECT ClientRect(void *);
RECT SetRect(int,int,int,int);
#endif
[LISTING FIVE]
/* ---------------- video.h ----------------- */
#ifndef VIDEO_H
#define VIDEO_H
#include "rect.h"
void getvideo(RECT, void far *);
void storevideo(RECT, void far *);
extern unsigned video_mode;
extern unsigned video_page;
void wputch(WINDOW, int, int, int);
int GetVideoChar(int, int);
void PutVideoChar(int, int, int);
void get_videomode(void);
void wputs(WINDOW, void *, int, int);
#define clr(fg,bg) ((fg)|((bg)<<4))
#define vad(x,y) ((y)*160+(x)*2)
#define ismono() (video_mode == 7)
#define istext() (video_mode < 4)
#define videochar(x,y) (GetVideoChar(x,y) & 255)
#endif
[LISTING SIX]
/* --------------------- video.c -------------------- */
#include <stdio.h>
#include <dos.h>
#include <string.h>
#include <conio.h>
#include "dflat.h"
static unsigned video_address;
/* -- read a rectangle of video memory into a save buffer -- */
void getvideo(RECT rc, void far *bf)
{
int ht = RectBottom(rc)-RectTop(rc)+1;
int bytes_row = (RectRight(rc)-RectLeft(rc)+1) * 2;
unsigned vadr = vad(RectLeft(rc), RectTop(rc));
hide_mousecursor();
while (ht--) {
movedata(video_address, vadr, FP_SEG(bf),
FP_OFF(bf), bytes_row);
vadr += 160;
(char far *)bf += bytes_row;
}
show_mousecursor();
}
/* -- write a rectangle of video memory from a save buffer -- */
void storevideo(RECT rc, void far *bf)
{
int ht = RectBottom(rc)-RectTop(rc)+1;
int bytes_row = (RectRight(rc)-RectLeft(rc)+1) * 2;
unsigned vadr = vad(RectLeft(rc), RectTop(rc));
hide_mousecursor();
while (ht--) {
movedata(FP_SEG(bf), FP_OFF(bf), video_address,
vadr, bytes_row);
vadr += 160;
(char far *)bf += bytes_row;
}
show_mousecursor();
}
/* -------- read a character of video memory ------- */
int GetVideoChar(int x, int y)
{
int c;
hide_mousecursor();
c = peek(video_address, vad(x,y));
show_mousecursor();
return c;
}
/* -------- write a character of video memory ------- */
void PutVideoChar(int x, int y, int c)
{
if (x < SCREENWIDTH && y < SCREENHEIGHT) {
hide_mousecursor();
poke(video_address, vad(x,y), c);
show_mousecursor();
}
}
/* -------- write a character to a window ------- */
void wputch(WINDOW wnd, int c, int x, int y)
{
int x1 = GetClientLeft(wnd)+x;
int y1 = GetClientTop(wnd)+y;
if (x1 < SCREENWIDTH && y1 < SCREENHEIGHT) {
hide_mousecursor();
poke(video_address,
vad(x1,y1),(c & 255) |
(clr(foreground, background) << 8));
show_mousecursor();
}
}
/* ------- write a string to a window ---------- */
void wputs(WINDOW wnd, void *s, int x, int y)
{
int x1 = GetLeft(wnd)+x;
int y1 = GetTop(wnd)+y;
if (x1 < SCREENWIDTH && y1 < SCREENHEIGHT) {
int fg = foreground;
int bg = background;
unsigned char *str = s;
char ss[200];
int ln[SCREENWIDTH];
int *cp1 = ln;
int len;
strncpy(ss, s, 199);
ss[199] = '\0';
clipline(wnd, x, ss);
str = (unsigned char *) ss;
hide_mousecursor();
while (*str) {
if (*str == CHANGECOLOR) {
str++;
foreground = (*str++) & 0x7f;
background = (*str++) & 0x7f;
continue;
}
if (*str == RESETCOLOR) {
foreground = fg;
background = bg;
str++;
continue;
}
*cp1++ = (*str & 255) |
(clr(foreground, background) << 8);
str++;
}
foreground = fg;
background = bg;
len = (int)(cp1-ln);
if (x1+len > SCREENWIDTH)
len = SCREENWIDTH-x1;
movedata(FP_SEG(ln), FP_OFF(ln), video_address,
vad(x1,y1), len*2);
show_mousecursor();
}
}
/* --------- get the current video mode -------- */
void get_videomode(void)
{
videomode();
/* ---- Monochrome Display Adaptor or text mode ---- */
if (ismono())
video_address = 0xb000;
else
/* ------ Text mode -------- */
video_address = 0xb800 + video_page;
}
[LISTING SEVEN]
/* ----------- console.c ---------- */
#include <conio.h>
#include <bios.h>
#include <dos.h>
#include "system.h"
#include "keys.h"
/* ----- table of alt keys for finding shortcut keys ----- */
char altconvert[] = {
ALT_A,ALT_B,ALT_C,ALT_D,ALT_E,ALT_F,ALT_G,ALT_H,
ALT_I,ALT_J,ALT_K,ALT_L,ALT_M,ALT_N,ALT_O,ALT_P,
ALT_Q,ALT_R,ALT_S,ALT_T,ALT_U,ALT_V,ALT_W,ALT_X,
ALT_Y,ALT_Z,ALT_0,ALT_1,ALT_2,ALT_3,ALT_4,ALT_5,
ALT_6,ALT_7,ALT_8,ALT_9,0
};
unsigned video_mode;
unsigned video_page;
static int near cursorpos[MAXSAVES];
static int near cursorshape[MAXSAVES];
static int cs = 0;
static union REGS regs;
#ifndef MSC
#define ZEROFLAG 0x40
/* ---- Test for keystroke ---- */
int keyhit(void)
{
_AH = 1;
geninterrupt(KEYBRD);
return (_FLAGS & ZEROFLAG) == 0;
}
#endif
/* ---- Read a keystroke ---- */
int getkey(void)
{
int c;
while (keyhit() == 0)
;
if (((c = bioskey(0)) & 0xff) == 0)
c = (c >> 8) | 0x80;
return c & 0xff;
}
/* ---------- read the keyboard shift status --------- */
int getshift(void)
{
regs.h.ah = 2;
int86(KEYBRD, ®s, ®s);
return regs.h.al;
}
/* ------- macro to wait one clock tick -------- */
#define wait() \
{ \
int now = peek(0x40,0x6c); \
while (now == peek(0x40,0x6c)) \
; \
}
/* -------- sound a buzz tone ---------- */
void beep(void)
{
wait();
outp(0x43, 0xb6); /* program the frequency */
outp(0x42, (int) (COUNT % 256));
outp(0x42, (int) (COUNT / 256));
outp(0x61, inp(0x61) | 3); /* start the sound */
wait();
outp(0x61, inp(0x61) & ~3); /* stop the sound */
}
/* -------- get the video mode and page from BIOS -------- */
void videomode(void)
{
regs.h.ah = 15;
int86(VIDEO, ®s, ®s);
video_mode = regs.h.al;
video_page = regs.x.bx;
video_page &= 0xff00;
video_mode &= 0x7f;
}
/* ------ position the cursor ------ */
void cursor(int x, int y)
{
videomode();
regs.x.dx = ((y << 8) & 0xff00) + x;
regs.x.ax = 0x0200;
regs.x.bx = video_page;
int86(VIDEO, ®s, ®s);
}
/* ------ get cursor shape and position ------ */
static void near getcursor(void)
{
videomode();
regs.h.ah = READCURSOR;
regs.x.bx = video_page;
int86(VIDEO, ®s, ®s);
}
/* ------- get the current cursor position ------- */
void curr_cursor(int *x, int *y)
{
getcursor();
*x = regs.h.dl;
*y = regs.h.dh;
}
/* ------ save the current cursor configuration ------ */
void savecursor(void)
{
if (cs < MAXSAVES) {
getcursor();
cursorshape[cs] = regs.x.cx;
cursorpos[cs] = regs.x.dx;
cs++;
}
}
/* ---- restore the saved cursor configuration ---- */
void restorecursor(void)
{
if (cs) {
--cs;
videomode();
regs.x.dx = cursorpos[cs];
regs.h.ah = SETCURSOR;
regs.x.bx = video_page;
int86(VIDEO, ®s, ®s);
set_cursor_type(cursorshape[cs]);
}
}
/* ------ make a normal cursor ------ */
void normalcursor(void)
{
set_cursor_type(0x0607);
}
/* ------ hide the cursor ------ */
void hidecursor(void)
{
getcursor();
regs.h.ch |= HIDECURSOR;
regs.h.ah = SETCURSORTYPE;
int86(VIDEO, ®s, ®s);
}
/* ------ unhide the cursor ------ */
void unhidecursor(void)
{
getcursor();
regs.h.ch &= ~HIDECURSOR;
regs.h.ah = SETCURSORTYPE;
int86(VIDEO, ®s, ®s);
}
/* ---- use BIOS to set the cursor type ---- */
void set_cursor_type(unsigned t)
{
videomode();
regs.h.ah = SETCURSORTYPE;
regs.x.bx = video_page;
regs.x.cx = t;
int86(VIDEO, ®s, ®s);
}
[LISTING EIGHT]
/* ------------- mouse.c ------------- */
#include <stdio.h>
#include <dos.h>
#include <stdlib.h>
#include <string.h>
#include "system.h"
static union REGS regs;
static void near mouse(int m1,int m2,int m3,int m4)
{
regs.x.dx = m4;
regs.x.cx = m3;
regs.x.bx = m2;
regs.x.ax = m1;
int86(MOUSE, ®s, ®s);
}
/* ---------- reset the mouse ---------- */
void resetmouse(void)
{
mouse(0,0,0,0);
}
/* ----- test to see if the mouse driver is installed ----- */
int mouse_installed(void)
{
unsigned char far *ms;
ms = MK_FP(peek(0, MOUSE*4+2), peek(0, MOUSE*4));
return (ms != NULL && *ms != 0xcf);
}
/* ------ return true if mouse buttons are pressed ------- */
int mousebuttons(void)
{
if (mouse_installed())
mouse(3,0,0,0);
return regs.x.bx & 3;
}
/* ---------- return mouse coordinates ---------- */
void get_mouseposition(int *x, int *y)
{
if (mouse_installed()) {
mouse(3,0,0,0);
*x = regs.x.cx/8;
*y = regs.x.dx/8;
}
}
/* -------- position the mouse cursor -------- */
void set_mouseposition(int x, int y)
{
if(mouse_installed())
mouse(4,0,x*8,y*8);
}
/* --------- display the mouse cursor -------- */
void show_mousecursor(void)
{
if(mouse_installed())
mouse(1,0,0,0);
}
/* --------- hide the mouse cursor ------- */
void hide_mousecursor(void)
{
if(mouse_installed())
mouse(2,0,0,0);
}
/* --- return true if a mouse button has been released --- */
int button_releases(void)
{
if(mouse_installed())
mouse(6,0,0,0);
return regs.x.bx;
}